/**
 * Copyright (c) 2015-2030 by Beijing Yanlight Co., Ltd.
 * All rights reserved.
 */
package com.yanlight.support.dev.order.notify;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.yanlight.app.dal.dao.DeveloperDAO;
import com.yanlight.app.dal.dao.OrderDAO;
import com.yanlight.app.dal.entity.Developer;
import com.yanlight.app.dal.entity.Order;
import com.yanlight.util.ToolsUtil;
import com.yanlight.util.WebUtil;

/**
 * 
 * @author haolw
 * @time 2018/02/08
 */
@Component
public class DevOrderNotifyHandler implements ApplicationListener<DevOrderNotifyEvent>, InitializingBean {
	@Autowired
	private OrderDAO orderDAO;
	@Autowired
	private DeveloperDAO developerDAO;
	private DevOrderNotifyDispatcher notifyDispatcher;
	private DevOrderStorageDispatcher storageDispatcher;

	@Override
	public void afterPropertiesSet() throws Exception {
		init();
	}

	private void init() {
		initDispatcher();
		initStorageOrder();
	}

	private void initDispatcher() {
		notifyDispatcher = new DevOrderNotifyDispatcher();
		storageDispatcher = new DevOrderStorageDispatcher();
		storageDispatcher.setOrderDAO(orderDAO);
		notifyDispatcher.setStorageDispatcher(storageDispatcher);
		notifyDispatcher.service();
		storageDispatcher.service();
	}

	private void initStorageOrder() {
		try {
			List<Order> notifyOrders = orderDAO.findDevNotifys();
			if (!CollectionUtils.isEmpty(notifyOrders)) {
				Set<Integer> operationIds = new HashSet<>(16);
				for (Order order : notifyOrders) {
					operationIds.add(order.getOperationId());
				}
				Map<Integer, String> devSecretMap = findDevSecrets(operationIds);
				DevOrderNotifyTask task = null;
				for (Order order : notifyOrders) {
					String notifyUrl = order.getNotifyUrl();
					if (StringUtils.isNotBlank(notifyUrl)) {
						if (!WebUtil.checkLocalUrl(notifyUrl)) {
							task = new DevOrderNotifyTask();
							task.setNotifyUrl(order.getNotifyUrl());
							task.setOutTradeNo(order.getOutTradeNo());
							task.setPayTime(order.getPayTime());
							task.setPayType(order.getPayType());
							task.setTotalFee(ToolsUtil.convertFee(order.getTotalFee()));
							task.setSecret(devSecretMap.get(order.getOperationId()));
							notifyDispatcher.addTask(task);
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Async
	public void onApplicationEvent(DevOrderNotifyEvent event) {
		String secret = findDevSecret(event.getOperationId());
		DevOrderNotifyTask task = event.toTask();
		task.setSecret(secret);
		notifyDispatcher.addTask(task);
	}

	private String findDevSecret(Integer devId) {
		return developerDAO.findById(devId).getSecret();
	}

	private Map<Integer, String> findDevSecrets(Collection<Integer> devIds) {
		Map<Integer, String> devSecretMap = new HashMap<>(16);
		List<Developer> developers = developerDAO.findByIds(devIds);
		for (Developer developer : developers) {
			devSecretMap.put(developer.getId(), developer.getSecret());
		}
		return devSecretMap;
	}

}
